<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring循环依赖深度解析</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
        }
        
        /* 首字下沉效果 */
        .drop-cap::first-letter {
            float: left;
            font-size: 4rem;
            line-height: 3rem;
            padding-right: 0.5rem;
            margin-top: 0.5rem;
            font-weight: 700;
            color: #4f46e5;
            font-family: 'Noto Serif SC', serif;
        }
        
        /* 代码块美化 */
        pre {
            background: #1e293b;
            color: #e2e8f0;
            border-radius: 12px;
            padding: 1.5rem;
            overflow-x: auto;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            position: relative;
        }
        
        pre::before {
            content: attr(data-language);
            position: absolute;
            top: 0.5rem;
            right: 1rem;
            font-size: 0.75rem;
            color: #64748b;
            text-transform: uppercase;
        }
        
        /* 卡片悬停效果 */
        .hover-card {
            transition: all 0.3s ease;
        }
        
        .hover-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
        }
        
        /* 渐变文字 */
        .gradient-text {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }
        
        /* 动画效果 */
        @keyframes fadeInUp {
            from {
                opacity: 0;
                transform: translateY(30px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }
        
        .animate-fadeInUp {
            animation: fadeInUp 0.8s ease-out;
        }
        
        /* 自定义滚动条 */
        ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }
        
        ::-webkit-scrollbar-track {
            background: #f1f5f9;
        }
        
        ::-webkit-scrollbar-thumb {
            background: #cbd5e1;
            border-radius: 4px;
        }
        
        ::-webkit-scrollbar-thumb:hover {
            background: #94a3b8;
        }
        
        /* 高亮标记 */
        .highlight {
            background: linear-gradient(180deg, transparent 60%, #fbbf24 60%);
            padding: 0 4px;
        }
        
        /* 编号列表美化 */
        .custom-ol {
            counter-reset: item;
            list-style: none;
        }
        
        .custom-ol li {
            counter-increment: item;
            position: relative;
            padding-left: 3rem;
            margin-bottom: 1.5rem;
        }
        
        .custom-ol li::before {
            content: counter(item);
            position: absolute;
            left: 0;
            top: 0;
            width: 2rem;
            height: 2rem;
            background: #4f46e5;
            color: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: 700;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="relative overflow-hidden bg-gradient-to-br from-indigo-600 via-purple-600 to-pink-500 text-white">
        <div class="absolute inset-0 bg-black opacity-20"></div>
        <div class="relative max-w-7xl mx-auto px-4 py-24 sm:px-6 lg:px-8">
            <div class="text-center animate-fadeInUp">
                <h1 class="text-5xl md:text-7xl font-bold mb-6">
                    Spring 循环依赖
                    <span class="block text-3xl md:text-4xl mt-4 font-light opacity-90">深度解析与实战指南</span>
                </h1>
                <p class="text-xl md:text-2xl max-w-3xl mx-auto opacity-90 leading-relaxed">
                    探索 Spring 框架中最具挑战性的问题之一，理解三级缓存机制的精妙设计
                </p>
                <div class="mt-8 flex justify-center space-x-4">
                    <span class="inline-flex items-center px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm">
                        <i class="fas fa-clock mr-2"></i> 阅读时间：15分钟
                    </span>
                    <span class="inline-flex items-center px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm">
                        <i class="fas fa-layer-group mr-2"></i> 深度：高级
                    </span>
                </div>
            </div>
        </div>
        <div class="absolute bottom-0 left-0 right-0">
            <svg viewBox="0 0 1440 120" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M0 120L60 105C120 90 240 60 360 45C480 30 600 30 720 37.5C840 45 960 60 1080 67.5C1200 75 1320 75 1380 75L1440 75V120H1380C1320 120 1200 120 1080 120C960 120 840 120 720 120C600 120 480 120 360 120C240 120 120 120 60 120H0Z" fill="white"/>
            </svg>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-6xl mx-auto px-4 py-16 sm:px-6 lg:px-8">
        
        <!-- 什么是循环依赖 -->
        <section class="mb-16 animate-fadeInUp">
            <div class="bg-white rounded-2xl shadow-xl p-8 hover-card">
                <h2 class="text-3xl font-bold mb-6 gradient-text flex items-center">
                    <i class="fas fa-circle-notch mr-3"></i> 什么是循环依赖
                </h2>
                <p class="text-lg text-gray-700 mb-6 drop-cap">
                    循环依赖是指N个类循环（嵌套）引用。通俗地讲就是N个Bean互相引用对方，最终形成<span class="highlight">闭环</span>。这种情况在复杂的企业级应用中并不罕见，特别是在服务层相互调用的场景下。
                </p>
                
                <!-- 循环依赖可视化 -->
                <div class="bg-gray-50 rounded-xl p-6 mt-8">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">
                        <i class="fas fa-diagram-project mr-2 text-indigo-600"></i> 循环依赖关系图
                    </h3>
                    <div class="mermaid text-center">
                        graph LR
                        A[Bean A] -->|依赖| B[Bean B]
                        B -->|依赖| C[Bean C]
                        C -->|依赖| A
                        style A fill:#4f46e5,stroke:#333,stroke-width:2px,color:#fff
                        style B fill:#7c3aed,stroke:#333,stroke-width:2px,color:#fff
                        style C fill:#a855f7,stroke:#333,stroke-width:2px,color:#fff
                    </div>
                </div>
            </div>
        </section>

        <!-- Spring Bean的循环依赖 -->
        <section class="mb-16 animate-fadeInUp" style="animation-delay: 0.2s;">
            <div class="bg-white rounded-2xl shadow-xl p-8 hover-card">
                <h2 class="text-3xl font-bold mb-6 gradient-text flex items-center">
                    <i class="fas fa-leaf mr-3"></i> Spring Bean的循环依赖
                </h2>
                
                <!-- Field注入循环依赖 -->
                <div class="mb-10">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">
                        <span class="inline-flex items-center">
                            <span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm mr-3">可解决</span>
                            Field属性注入循环依赖
                        </span>
                    </h3>
                    
                    <div class="grid md:grid-cols-2 gap-6">
                        <div>
                            <pre data-language="java"><code>@Component
public class A {
    @Autowired
    private B b;
}</code></pre>
                        </div>
                        <div>
                            <pre data-language="java"><code>@Component
public class B {
    @Autowired
    private A a;
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="mt-6 bg-blue-50 border-l-4 border-blue-500 p-4 rounded">
                        <p class="text-blue-800">
                            <i class="fas fa-info-circle mr-2"></i>
                            <strong>解决方案：</strong>通过设置 <code class="bg-blue-100 px-2 py-1 rounded">spring.main.allow-circular-references=true</code> 可以开启Spring解决循环依赖的功能。
                        </p>
                    </div>
                </div>
                
                <!-- 构造器注入循环依赖 -->
                <div>
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">
                        <span class="inline-flex items-center">
                            <span class="bg-red-100 text-red-800 px-3 py-1 rounded-full text-sm mr-3">无法解决</span>
                            构造器注入循环依赖
                        </span>
                    </h3>
                    
                    <div class="grid md:grid-cols-2 gap-6">
                        <div>
                            <pre data-language="java"><code>@Service
public class A {
    private B b;
    
    public A(B b) {
        this.b = b;
    }
}</code></pre>
                        </div>
                        <div>
                            <pre data-language="java"><code>@Service
public class B {
    private A a;
    
    public B(A a) {
        this.a = a;
    }
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="mt-6 bg-red-50 border-l-4 border-red-500 p-4 rounded">
                        <p class="text-red-800">
                            <i class="fas fa-exclamation-triangle mr-2"></i>
                            <strong>根本原因：</strong>Spring解决循环依赖依靠的是Bean的"中间态"概念，而构造器是完成实例化的必要步骤，无法产生中间态。
                        </p>
                    </div>
                </div>
            </div>
        </section>

        <!-- 三级缓存机制 -->
        <section class="mb-16 animate-fadeInUp" style="animation-delay: 0.4s;">
            <div class="bg-white rounded-2xl shadow-xl p-8 hover-card">
                <h2 class="text-3xl font-bold mb-6 gradient-text flex items-center">
                    <i class="fas fa-database mr-3"></i> Spring容器的三级缓存
                </h2>
                
                <p class="text-lg text-gray-700 mb-8">
                    Spring使用三级缓存机制来解决循环依赖问题，其中二级缓存解决基本的循环依赖，三级缓存主要解决AOP代理的问题。
                </p>
                
                <!-- 三级缓存结构 -->
                <div class="grid md:grid-cols-3 gap-6 mb-8">
                    <div class="bg-gradient-to-br from-blue-50 to-blue-100 p-6 rounded-xl border-2 border-blue-200">
                        <div class="flex items-center mb-4">
                            <span class="bg-blue-500 text-white w-10 h-10 rounded-full flex items-center justify-center font-bold mr-3">1</span>
                            <h4 class="text-xl font-semibold text-blue-900">一级缓存</h4>
                        </div>
                        <code class="block bg-white p-3 rounded text-sm mb-3">singletonObjects</code>
                        <p class="text-blue-800">存储完全初始化好的单例Bean</p>
                    </div>
                    
                    <div class="bg-gradient-to-br from-purple-50 to-purple-100 p-6 rounded-xl border-2 border-purple-200">
                        <div class="flex items-center mb-4">
                            <span class="bg-purple-500 text-white w-10 h